/**
 * 
 */
package net.betou.trade.main.manager.impl;

import java.util.List;
import java.util.Set;

import net.betou.common.hibernate3.Updater;
import net.betou.common.page.Pagination;
import net.betou.trade.entity.main.AgentAndAdmins;
import net.betou.trade.entity.main.Role;
import net.betou.trade.main.dao.RoleDao;
import net.betou.trade.main.manager.RoleMng;
import net.betou.trade.web.DBConstants;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * @author 叶装装
 * 
 */
@Service
@Transactional
public class RoleMngImpl implements RoleMng{

	public Role deleteById( Integer id ) {
		return dao.deleteById( id );
	}

	public Role [ ] deleteByIds( Integer [ ] ids ) {
		Role [ ] beans = new Role [ ids.length ];
		for ( int i = 0, len = ids.length; i < len; i++ ){
			beans[ i ] = deleteById( ids[ i ] );
		}
		return beans;
	}

	/**
	 * 查找机构默认角色
	 * 
	 * @return
	 */
	@Transactional( readOnly = true )
	public Role findAgency( ) {
		return dao.findByIdentity( DBConstants.SYSTEM_AGENCY_IDENTITY );
	}

	/**
	 * 查找代理默认角色
	 * 
	 * @return
	 */
	@Transactional( readOnly = true )
	public Role findProxy( ) {
		return dao.findByIdentity( DBConstants.SYSTEM_PROXY_IDENTITY );
	}

	@Transactional( readOnly = true )
	public List< Role > getAgentRoleAndDefaultList( AgentAndAdmins admin ) {
		// 如果是system, 读取全部
		// 如果不是system, 按照当前分组的level来读取并且是属于自己的

		boolean system = admin.getSystem( );

		if( system ){
			return dao.getRoleList( true, true, null, null, null, null, null );
		}

		return dao.getRoleList( true, true, admin.getSearchSettingRole( ).getLevel( ), null, null, null, null );

	}

	@Transactional( readOnly = true )
	public Role findAdminRole( Integer id ) {
		return dao.findByAgentOrAdminRole( true, id );
	}

	@Transactional( readOnly = true )
	public Role findAgentRole( AgentAndAdmins admin, Integer id ) {
		boolean system = admin.getSystem( );

		// 如果是管理员，则获取数据
		if( system ){
			return dao.findById( id );
		}
		// 如果不是管理员，则只能查询自己的数据
		return dao.findMyData( admin.getId( ), id );
	}

	@Transactional( readOnly = true )
	public Role findById( Integer id ) {
		return dao.findById( id );
	}

	@Transactional( readOnly = true )
	public List< Role > getAdminRoleList( Integer level, String searchProperty, String searchValue, String orderProperty, String orderDirection ) {
		return dao.getRoleList( false, true, level, searchProperty, searchValue, orderProperty, orderDirection );
	}

	@Transactional( readOnly = true )
	public List< Role > getAdminRoleList( String searchProperty, String searchValue, String orderProperty, String orderDirection ) {
		return dao.getRoleList( null, true, null, searchProperty, searchValue, orderProperty, orderDirection );
	}

	@Transactional( readOnly = true )
	public List< Role > getAgentRoleList( String searchProperty, String searchValue, String orderProperty, String orderDirection ) {
		return dao.getRoleList( null, false, null, searchProperty, searchValue, orderProperty, orderDirection );
	}

	@Transactional( readOnly = true )
	public List< Role > getAgentRoleList( AgentAndAdmins admin ) {
		// 如果是系统管理员，则不查找等级
		if( admin.getSystem( ) ){
			return dao.getAgentRoleList( null, admin.getId( ) );
		}
		return dao.getAgentRoleList( admin.getSearchSettingRole( ).getLevel( ), admin.getId( ) );
	}

	@Transactional( readOnly = true )
	public Pagination getAgentPage( AgentAndAdmins admin, String searchProperty, String searchValue, String orderProperty, String orderDirection, int pageSize, int pageNo ) {
		Pagination pagination;
		boolean system = admin.getSystem( );

		if( system ){
			pagination = dao.getAgentPage( null, null, searchProperty, searchValue, orderProperty, orderDirection, pageSize, pageNo );
		}else{
			pagination = dao.getAgentPage( admin.getSearchSettingRole( ).getLevel( ), admin.getId( ), searchProperty, searchValue, orderProperty, orderDirection, pageSize, pageNo );
		}

		return pagination;
	}

	public Role update( Role bean, Set< String > perms ) {

		Updater< Role > updater = new Updater< Role >( bean );
		bean = dao.updateByUpdater( updater );
		updater.exclude( "roleDefault" ); // 不更新是否默认
		updater.exclude( "allowRead" );
		updater.exclude( "identity" ); // 不包括这三种

		bean.setPerms( perms );

		afterUpdate( bean, perms );

		return bean;
	}

	@Transactional( readOnly = true )
	public List< Role > getAgentRoleList( Integer level ) {
		if( level == null ){
			level = 1; // 不查找出最顶级的
		}
		return dao.getRoleList( null, false, level, null, null, null, null );
	}

	public Role saveAdminRole( Role bean, Set< String > perms ) {
		bean.setManager( true );
		bean.setAllowRead( false ); // 系统的角色不允许被读取
		bean.setIdentity( null ); // 没有标识符
		bean.setAdmin( null ); // 系统角色没有相关的管理员信息
		return save( bean, perms );
	}

	public Role saveAgentRole( AgentAndAdmins admin, Role bean, Set< String > perms ) {
		bean.setManager( false );
		bean.setAllowRead( true );
		bean.setAdmin( admin );
		bean.setIdentity( null );

		Integer level = dao.findMaxLevel( admin.getId( ) );

		if( level == 0 ){
			level = admin.getDeep( );
		}

		bean.setLevel( level + 1 );

		return save( bean, perms );
	}

	private Role save( Role bean, Set< String > perms ) {
		bean.setPerms( perms );
		bean.init( );
		dao.save( bean );
		return bean;
	}

	private void afterUpdate( Role bean, Set< String > perms ) {
		// 三种情况， 是默认的，并且是系统角色，并且允许读取
		if( !bean.getRoleDefault( ) ){
			return;
		}
		
		if( !bean.getManager( ) ){
			return;
		}
		
		if( !bean.getAllowRead( ) ){
			return;
		}

		String identity = bean.getIdentity( ) + "d"; // 先查询出identity,根据identity查询出所有的数据，然后进行批量更新, 相信这数据不会超过1000条

		List< Role > roleList = dao.getAgentRoleListByIdentity( identity );
		if( roleList == null || roleList.size( ) == 0 ){
			return;
		}

		for ( Role r : roleList ){
			Updater< Role > updater = new Updater< Role >( r );
			r = dao.updateByUpdater( updater );
			updater.exclude( "roleDefault" ); // 不更新是否默认
			updater.exclude( "allowRead" );
			updater.exclude( "identity" ); // 不包括这三种

			r.setPerms( perms );
		}

	}
	
	public Role findMyAgency( Integer selfId ){
		return dao.findMyDefaultRole( selfId, DBConstants.DEFINED_AGENCY_IDENTITY );
	}
	
	public Role findMyProxy( Integer selfId ){
		return dao.findMyDefaultRole( selfId, DBConstants.DEFINED_PROXY_IDENTITY );
	}

	private RoleDao dao;

	@Autowired
	public void setDao( RoleDao dao ) {
		this.dao = dao;
	}

}
